VRML Authoring Hints and Tips

Introduction

Authoring a compelling virtual world that looks good on VRML viewers from PCs up to Reality Engines is not easy. Most of the effort will be grunt work - making multiple versions of your models that range in polygonal complexity, yet still look good. By doing this, it is possible to make VRML worlds which look their best on all viewers, without writing to the lowest common denominator, and without excluding low-end machines from viewing your scenes.

This document describes suggestions for getting the best performance out of all viewers, but with a decided bias towards WebSpace (tm), the VRML viewer. If you have a good grasp of the WWWAnchor, WWWInline and LOD nodes, you can just cut to the chase.

This document assumes you are familiar with the Open Inventor file format, and with the VRML specification. This and other related info can be obtained from:

Building Models and Scenes

Modeling Tips

Use your favorite modeler to create model geometry and scene placement. Here are some tips to keep in mind:

Translators

An Inventor to VRML translator, ivToVRML, will be available soon.

It converts standard Inventor files into the subset of Inventor which is VRML.This subset is described in the Inventor/VRML Overview.

Using the LOD Node

Note: This discussion describes the LOD node, which is different than the LevelOfDetail node described in the VRML draft spec. This new node uses a distance-based, instead of a screen-space-based algorithm. WebSpace will support both nodes for the near future. You can read about the LOD proposal in the VRML mailing list. Here is the text of the LOD proposal:

This group node is used to allow applications to switch between various representations of objects automatically. The children of this node typically represent the same object or objects at varying levels of detail, from highest detail to lowest.

The specified center point of the LOD is transformed by the current transformation into world space, and the distance from the transformed center to the world-space eye point is calculated. If the distance is less than the first value in the ranges array, then the first child of the LOD group is drawn. If between the first and second values in the ranges array, the second child is drawn, etc. If there are N values in the ranges array the LOD nodes should have N+1 children. Specifying too few children will result in the last child being used repeatedly for the lowest levels of detail; extra children will be ignored if too many children are specified. Each value in the ranges array should be less than the previous value, otherwise results are undefined.

FILE FORMAT/DEFAULTS
LOD {
   ranges [ ]   # MFFloat
   center 0 0 0 # SFVec3f
} 

Modeling Hints for LOD Children

A good rule of thumb is to make at least three versions of each model:

These polygon counts are only representative. As discussed in a later section, you need to also manage the overall scene complexity.

You may also want to have a fourth child which has no geometry, if it is OK for the object to disappear when it is very far away. Which leads us to the next topic...

An Example

Note: For clarity, this example does not use the WWWInline node. However, as described in the next section, judicious use of the WWWInline node in combination with the LOD node is necessary to achieve optimal viewer performance, especially when pulling data across the net.

# A mountain object
DEF Everest LOD {
  ranges [100, 1000, 10000]  # n ranges for n+1 children
  center 0 1000 0            # assuming mountain is 2000 high

  # High complexity, textured
  DEF EverestHi Separator {
    Separator {
      # Coordinates, textures and geometry for a 1200
      # polygon version of the mountain.
      ...
    }
  }

  # Medium complexity
  DEF EverestMed Separator {
    Separator {
      # Coordinates and geometry for a 600
      # polygon version of the mountain.
    }
  }

  # Low complexity
  DEF EverestLow Separator {
    Separator {
      # Coordinates, textures and geometry for a 8
      # polygon version of the mountain. Perhaps just
      # two four-sided pyramids
    }
  }

  # Invisible version of the mountain. Rendered when
  # the mountain is really far away.
  Group {
  }
}

Using the WWWInline Node

The WWWInline is used to delay the loading of some portion of a VRML scene. The URL specified by the Inline node is only fetched by the viewer when it is needed, such as when the viewer decides that it wants to render what is represented by the WWW Inline.

For this reason, it is natural to represent the children of an LOD node as WWWInline nodes. Imagine the example from above was accessed by a viewer on a low-end PC. It would go to all the trouble of reading all four children of the LOD node, including the 1200 polygon textured version, even though it probably will never render it.

If instead we wrap the LOD children in WWWInline nodes, a given child will only be read if the LOD node decides it should be rendered. This saves unneccesary reading of data over a potentially slow network connection.

Since we want to insure that something is read right away to be available for display, do not wrap the lowest complexity version of the model in an Inline node. Also, note that some viewers (like the SGI viewer) will read the WWWInline nodes as a background process, 'popping' the result into the viewer when it becomes available. By not inlining the low-res version, the user still sees something while the higher res version is being fetched.

Specifying the Bounding Box

It is critical to specify an accurate bounding box in the WWWInline node. The bounding box allows the LOD node to cull a WWWInline node without actually reading its contents. Use the vrmlinfo utility that was shipped with the WebSpace alpha distribution to find bounding box information about a VRML or Inventor object. Also note that the ivToVRML utility will fill in the bounding box info automatically.

The same example, using WWWInline nodes

Since we will wrap our objects in WWWInline nodes, we need to keep them as separate VRML files...

#VRML V1.0 ascii
#File EverestHi.vrml
Separator {
  # Coordinates, textures and geometry for a 1200
  # polygon version of the mountain.
  ...
}

#VRML V1.0 ascii
#File EverestMed.vrml
Separator {
  # Coordinates and geometry for a 600
  # polygon version of the mountain.
}

Then we have our world, which references these files. Note that the URL can be relative to the current URL.

# A mountain object
DEF Everest LOD {
  ranges [100, 1000, 10000]  # n ranges for n+1 children
  center 0 1000 0            # assuming mountain is 2000 high

  # Hi Complexity
  DEF EverestHi Separator {
    WWWInline {
      name "EverestHi.vrml"
      bboxSize   200 400 200
      bboxCenter 0 200 0
    }
  }

  # Medium complexity
  DEF EverestMed Separator {
    WWWInline {
      name "EverestMed.vrml"
      bboxSize   200 400 200
      bboxCenter 0 200 0
    }
  }


  # Low complexity, not inlined
  DEF EverestLow Separator {
    Separator {
      # Coordinates, textures and geometry for a 8
      # polygon version of the mountain. Perhaps just
      # two four-sided pyramids
    }
  }

  # Invisible version of the mountain. Rendered when
  # the mountain is really far away.
  Group {
  }
}

Managing Overall Scene Complexity

Besides managing the complexity of individual objects in the scene, it is important to keep the overall scene complexity in mind. For any given position of the camera, you must ask "What will be in view?" and "How many polygons am I trying to draw?" It is important that for a given view, you do not try to draw too much for a given viewer platform.

Here are some polygon-per-scene guidelines for a small range of platforms, assuming 15 frames per second:

Pentium-90, NT       1300 (size?, lit, no texture)
XL (Indy/Indigo2)    1600 (10x10, lit, no texture)
XZ (Indy/Indigo2)    4400 (10x10, lit, no texture)
Extreme (Indigo2)   10300 (10x10, lit, no texture)
RealityEngine2      30000 (10x10 [50 pixel/tri] tmesh, lit, textured)

Using the WWWAnchor Node

Finally, edit your VRML scene and add WWWAnchor nodes around those objects that should be hyperlinked. Note that Anchors can be used to limit the size of a scene to a manageable complexity. For example, instead of having a wide open space with all objects visible, have closed rooms, where clicking on a door takes you to a new scene:

# Room
Separator {
    Separator {
        # closed room geometry here
    }

    # Door to next room
    WWWAnchor {
        name "rooms/NextRoom.vrml"

        # Door Geometry
        Separator {
            Transform {
                translation 3 4 1
                rotation 0 1 0 1.5407
            }
            LOD {
                ranges [4, 16]
                center 1.5 4 .05

                WWWInline {
                    name "geom/DoorHi.vrml"
                    bboxSize 3 8 .1
                    bbox Center 0 0 0
                }
                WWWInline {
                    name "geom/DoorMed.vrml"
                    bboxSize 3 8 .1
                    bbox Center 0 0 0
                }
                Separator {
                    Cube {
                        width 3 height 8 depth .1
                    }
                }
            }
        }
    }
}

Other Hints for WebSpace

WebSpace will look for these hints in a VRML file.

Viewer Paradigm

This specifies the preferred viewing paradigm for the scene. Possible choices are "examiner" and "walk".

DEF Viewer Info {
  string "examiner"
}

Viewer Speed

This specifies the default walking speed for the walk viewer. The velocity is in "units per second." For example, if your world is defined in terms of meters (which by the way, is what the VRML spec defines), the following hint will move the user 28 meters forward if the user holds the forward key for one second:

DEF ViewerSpeed Info {
  string "28.0"
}

If this hint is not specified, WebSpace will try to pick a reasonable speed based on the size of the scene.

VRML Title

This title hint will be displayed in the WebSpace title bar.

DEF Title Info {
  string "My VRML Scene Title"
}

VRML Document Info

This hint defines scene information that will be displayed, along with the title and URL, if the user chooses "Document Info" from the WebSpace File menu.

DEF SceneInfo Info {
  string "This scene was designed by Bozo T. Clown in 1995 using the ClownEdit modeler."
}

Background Color

This will set the background color of the WebSpace window to the given RGB value:

DEF BackgroundColor Info {
  string ".2 .2 .2"
}

Vantage Points

Vantage points are interesting places to put the camera in the scene, like "Kodak Moment" stops. To have vantage points in your scene, simply name your cameras using DEF, and put them under a switch node:

DEF Cameras Switch {
  whichChild 0
  DEF Home_View PerspectiveCamera {
    position 123 0 234
    orientation 0 1 0 .1
  }
  DEF Treasure_View PerspectiveCamera {
    position 456 0 234
    orientation 0 1 0 .8
  }
}

The names of these cameras will be added to the vantage points UI in WebSpace. The Switch node should be named "Cameras" as shown. The value of whichChild field will determine the default camera. If whichChild is not set, the first camera will be used.

Auto Clipping Planes

By default, WebSpace will automatically adjust the near and far clipping planes to be as tight as possible around the scene, based on the scene's bounding box. Occasionally, this will produce undesired results, such as having a near clipping plane which is too far away from the eye.

If you are experiencing this problem, use this hint:

DEF AutoClip Info {
  string "off"
}

If you do use this hint, make sure that all of the cameras defined in your scene have appropriate values set for nearDistance and farDistance.

Using File Compression (UNIX Versions Only)

File compression of VRML files is supported, and can dramatically reduce the size of VRML files, which subsequently reduces required network bandwidth. After authoring your VRML files, you can compress them with 'compress' or 'gzip' (preferred). The gzip executable (and even source source code) is included with the Netscape distribution.

Files which you compress with 'compress' should end in .wrl.Z

Files which you compress with 'gzip' should end in .wrl.gz (preferred) or .wrl.z or .wrz

Summary

General Methodology

Howard Look
howardl@sgi.com
Last updated April 26, 1995.